﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Beacon.SPC
{
    /// <summary>
    /// Western Electric rule 1:
    /// Any single data point falls outside the 3σ limit from the centerline.
    /// </summary>
    class WERule1 : ISpcRule
    {
        #region Members
        private const int PointCount = 1;

        SpcControlSide _side = SpcControlSide.Both;
        SpcControlLimit _limit = null;
        #endregion

        #region Constructor
        public WERule1(SpcControlSide side, SpcControlLimit limit)
        {
            _side = side;
            _limit = limit;
        }

        #endregion

        #region ISpcRule Members

        /// <summary>
        /// return rule type
        /// </summary>
        /// <returns></returns>
        public SpcRules RuleType()
        {
            return SpcRules.WERule1;
        }

        /// <summary>
        /// return rule point count
        /// </summary>
        /// <returns></returns>
        public int GetRulePointCount()
        {
            return PointCount;
        }

        /// <summary>
        /// add point
        /// </summary>
        /// <param name="data" type="double"></param>
        /// <returns> true if data is violated the rule, others false</returns>
        public bool AddPoint(double data)
        {
            if (double.IsNaN(data))
                return false;
            switch(_side)
            {
                case SpcControlSide.Lower:
                    if(data< _limit.LCL)
                        return true;
                    break;
                case SpcControlSide.Upper:
                    if( data < _limit.UCL)
                        return true;
                    break;
                case SpcControlSide.Both:
                    if(data< _limit.LCL || data> _limit.UCL)
                        return true;
                    break;
            }
            return false;
        }

        /// <summary>
        /// add point with sample size
        /// limits for data point will be calculated with sample size.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="sampleSize"></param>
        /// <returns>true if data is violated the rule, others false</returns>
        public bool AddPoint(double data, double sampleSize)
        {

            if (sampleSize < 0) 
                return false;

            // calculate new limit for given new sample size.
            _limit.Calculate((int)sampleSize);
            return AddPoint(data);
        }

        /// <summary>
        /// reset the rule.
        /// clear the queue in rule instance.
        /// </summary>
        public void Reset()
        {
        }

        #endregion
    }
}
